package com.gf.framework.rabbitmq.model;

import com.gf.framework.common.utils.map.GfHashMap;
import com.gf.framework.common.utils.map.GfMap;
import lombok.*;

import java.util.*;

/**
 * @author gaofei
 * @date 2022/6/9 19:47
 */
@Data
@AllArgsConstructor
@NoArgsConstructor
@Builder
public class QueueInfo {
    private String name;

    /**
     * Classic 经典
     * Quorum 新的队列类型，适用于对数据安全、容错方面要求高于低延迟等其他特性的场景
     * Stream 类似kafka的队列，持久化到磁盘，可以自由选择读取位置
     */
    private String type = "Classic";


    /**
     * 是否持久化
     */
    private boolean durable = true;

    /**
     * 是否私有
     */
    private boolean exclusive = false;

    /**
     * 没有消费者后自动删除
     */
    private boolean autoDelete = false;

    /**
     * 队列超过多长时间没被使用后删除
     */
    private Long autoExpire;

    /**
     * 队列中的消息过期时间
     */
    private Long messageTtl;

    /**
     * queue溢出行为，这将决定当队列达到设置的最大长度或者最大的存储空间时发送到消息队列的消息的处理方式；
     * 有效的值是：
     * drop-head（删除queue头部的消息）、
     * reject-publish（最近发来的消息将被丢弃）、
     * reject-publish-dlx（拒绝发送消息到死信交换器）
     * 类型为quorum 的queue只支持drop-head;
     */
    private String overFlow;

    /**
     * 只允许一个活跃的消费者
     */
    private boolean singleActiveConsumer;

    /**
     * 死信交换机
     */
    private String deadLetterExchange;

    /**
     * 死信routingKey
     */
    private String deadLetterRoutingKey;

    /**
     * 最大长度
     */
    private Long maxLength;

    /**
     * 数据最大长度
     */
    private Long maxLengthBytes;

    /**
     * 队列支持的最大优先级数;如果未设置，队列将不支持消息优先级。
     */
    private Long maxPriority;

    /**
     * lazy
     * 将队列设置为延迟模式，在磁盘上保留尽可能多的消息以减少内存使用;如果未设置，队列将保留内存缓存以尽快传递消息。
     */
    private String queueMode;

    List<BindingInfo> bindingInfos;

    public QueueInfo binding(BindingInfo bindingInfo) {
        if (bindingInfos == null) {
            bindingInfos = new ArrayList<>();
        }
        this.bindingInfos.add(bindingInfo);
        return this;
    }

    public Map<String, Object> getArguments() {
        return new GfHashMap<String, Object>().
                ofNotNull("x-expires", autoExpire).
                ofNotNull("x-message-ttl", messageTtl).
                ofNotNull("x-overflow", overFlow).
                ofNotNull("x-single-active-consumer", singleActiveConsumer).
                ofNotNull("x-dead-letter-exchange", deadLetterExchange).
                ofNotNull("x-dead-letter-routing-key", deadLetterRoutingKey).
                ofNotNull("x-max-length", maxLength).
                ofNotNull("x-max-length-bytes", maxLengthBytes).
                ofNotNull("x-max-priority", maxPriority).
                ofNotNull("x-queue-mode", queueMode);
    }

    public QueueInfo(String name) {
        this(name, null);
    }

    public QueueInfo(String name, List<BindingInfo> bindingInfos) {
        this(name, true, false, bindingInfos);
    }

    public QueueInfo(String name, Boolean durable, Boolean autoDelete, List<BindingInfo> bindingInfos) {
        setName(name);
        setDurable(durable);
        setAutoDelete(autoDelete);
        setBindingInfos(bindingInfos);
    }
}
